/* Copyright 2010 by Matt Van Der Westhuizen */

package org.chaoticengine.ast.pattern;

import org.chaoticengine.cgll.camera.Entity;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Vector2f;
import org.newdawn.slick.state.StateBasedGame;

/**
 * ViewController is the Observer class from the Subject-Observer pattern, but
 * with user-interface control methods rolled in as well.
 * 
 * @author Matt Van Der Westhuizen <mattpwest@gmail.com>
 */
public abstract class ViewController<T extends Model> implements Entity {
    protected Vector2f position = new Vector2f();
    protected Rectangle bounds = new Rectangle(0, 0, 0, 0);
    protected boolean selected = false;
    protected boolean hasFocus = false;

    public abstract void refresh(T model);
    public abstract T getModel();
    public abstract void update(GameContainer gc, StateBasedGame sbg, int delta);
    public abstract void render(GameContainer gc, StateBasedGame sbg, Graphics grphcs)
            throws SlickException;
    public abstract void onMouseEnter();
    public abstract void onMouseExit();
    public abstract void onMouseMove(int oldx, int oldy, int newx, int newy);
    public abstract void onMouseClick(int x, int y, int button);
    public abstract void onMouseRelease(int x, int y,int button);
    public abstract void onMouseWheelUp();
    public abstract void onMouseWheelDown();
    public abstract void keyPressed(int key, char c);
    public abstract void keyReleased(int key, char c);
    public abstract void onSelect();
    public abstract void onDeselect();
    

    public Vector2f getPosition() {
        return position;
    }

    public void setPosition(Vector2f position) {
        this.position = position;
        this.bounds.setX(position.x);
        this.bounds.setY(position.y);
    }

    public Rectangle getBoundingRectangle() {
        return(bounds);
    }

    public void setBoundingRectangle(Rectangle rect) {
        this.bounds = rect;
        this.bounds.setX(position.x);
        this.bounds.setY(position.y);
    }

    public boolean getSelected() {
        return(selected);
    }

    public void setSelected(boolean b) {
        selected = b;

        if (b) {
            onSelect();
        } else {
            onDeselect();
        }
    }

    public boolean hasFocus() {
        return(hasFocus);
    }

    public void setFocus(boolean focus) {
        this.hasFocus = focus;
    }
}
